package com.paipai.config;

import java.util.HashMap;
import java.util.Map;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitConfig {

	/**
	 * 延迟队列 TTL 名称
	 */
	private static final String REGISTER_DELAY_QUEUE = "order.sms.delay.queue";
	
	
	/**
	 * 延时交换机
	 * DLX，dead letter发送到的 exchange TODO 此处的 exchange 很重要,具体消息就是发送到该交换机的
	 */
	public static final String REGISTER_DELAY_EXCHANGE = "order.sms.delay.exchange";
	
	
	/**
	 * routing key 名称 TODO 此处的 routingKey 很重要要,具体消息发送在该 routingKey 的
	 */
	public static final String DELAY_ROUTING_KEY = "";
	
	
	
	//死信队列
	public static final String REGISTER_QUEUE_NAME = "order.sms.letter.queue";
	//死信交换机
	public static final String REGISTER_EXCHANGE_NAME = "order.sms.letter.exchange";
	//死信转发的key 也是死信的路由键
	public static final String ROUTING_KEY = "all";

	/**
	 * 延迟队列配置
	 * 
	 * 1、params.put("x-message-ttl", 5 * 1000); TODO 第一种方式是直接设置 Queue 延迟时间
	 * 但如果直接给队列设置过期时间,这种做法不是很灵活,（当然二者是兼容的,默认是时间小的优先）
	 * 
	 * 2、rabbitTemplate.convertAndSend(book, message -> {
	 * message.getMessageProperties().setExpiration(2 * 1000 + ""); return message;
	 * 
	 * }); TODO 第二种就是每次发送消息动态设置延迟时间,这样我们可以灵活控制
	 * 
	 **/
	@Bean
	public Queue delayProcessQueue() {
		Map<String, Object> params = new HashMap<String, Object>();
		// 成为死信后 将要去到的死信交换机
		params.put("x-dead-letter-exchange", REGISTER_EXCHANGE_NAME);
		// 成为死信后 携带的路由key 跟死信路由key相匹配
		params.put("x-dead-letter-routing-key", ROUTING_KEY);
		return new Queue(REGISTER_DELAY_QUEUE, true, false, false, params);
	}
	
	
	/**
	 * 
     * 需要将一个队列绑定到交换机上，要求该消息与一个特定的路由键完全匹配。
     * 这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “dog”，则只有被标记为“dog”的消息才被转发，不会转发dog.puppy，也不会转发dog.guard，只会转发dog。
     * TODO 它不像 TopicExchange 那样可以使用通配符适配多个
     *
     * @return DirectExchange
     */
    @Bean
    public DirectExchange delayExchange() {
        return new DirectExchange(REGISTER_DELAY_EXCHANGE);
    }

    @Bean
    public Binding dlxBinding() {
        return BindingBuilder.bind(delayProcessQueue()).to(delayExchange()).with(DELAY_ROUTING_KEY);
    }
    
    
    
    /**
     * 私信队列
     * @return
     */
    
    @Bean
    public Queue registerBookQueue() {
        return new Queue(REGISTER_QUEUE_NAME, true);
    }

    /**
     * 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。
     * 符号“#”匹配一个或多个词，符号“*”匹配不多不少一个词。因此“audit.#”能够匹配到“audit.irs.corporate”，但是“audit.*” 只会匹配到“audit.irs”。
     **/
    @Bean
    public TopicExchange registerBookTopicExchange() {
        return new TopicExchange(REGISTER_EXCHANGE_NAME);
    }

    @Bean
    public Binding registerBookBinding() {
        // TODO 如果要让延迟队列之间有关联,这里的 routingKey 和 绑定的交换机很关键
        return BindingBuilder.bind(registerBookQueue()).to(registerBookTopicExchange()).with(ROUTING_KEY);
    }



}
